package com.free.ui;

import android.app.Dialog;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;


/**
 * Dialog基类，提供基本的“确定”，“取消”按钮和title与message的显示。子类可以继承Builder,在content
 * layout中添加其他控件进行自定义。tips:cancel的回调不需要调用dialog.dismiss()，控件会自动调用
 */
public class FengjrDialog extends Dialog implements View.OnClickListener {

    private OnButtonClickListener mOnButtonClickListener;

    protected View mDialogContentView;

    private boolean mButtonInverse;

    private boolean mUseSystemAlert;

    public FengjrDialog(Context context) {
        super(context);
    }

    public FengjrDialog(Context context, int theme) {
        super(context, theme);
    }

    @Override
    public void onClick(View v) {
        final int id = v.getId();
        if (id == R.id.positiveButton) {
            if (mOnButtonClickListener != null) {
                if (mButtonInverse) {
                    mOnButtonClickListener.onCancelButtonClick(this);
                    dismiss();
                } else {
                    mOnButtonClickListener.onOKButtonClick(this);
                }
            }
        } else if (id == R.id.negativeButton) {
            if (mOnButtonClickListener != null) {
                if (mButtonInverse) {
                    mOnButtonClickListener.onOKButtonClick(this);
                } else {
                    mOnButtonClickListener.onCancelButtonClick(this);
                    dismiss();
                }
            }
        }
    }

    public void setOnButtonClickListener(OnButtonClickListener l) {
        mOnButtonClickListener = l;
    }

    public void setTitleText(String text) {
        if (!TextUtils.isEmpty(text)) {
            ((TextView) mDialogContentView.findViewById(R.id.title)).setText(text);
        }
    }

    private void buildDialogInternal(View contentView) {
        setContentView(contentView);

        mDialogContentView = contentView;

        DisplayMetrics dm = getContext().getResources().getDisplayMetrics();
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.width = dm.widthPixels - (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 80, dm);
        lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
        if (mUseSystemAlert) {
            lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
                    | WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
        }

        final int minHeight = (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, 118, dm
        );
        contentView.measure(
                View.MeasureSpec.makeMeasureSpec(lp.width, View.MeasureSpec.EXACTLY),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
        );
        final int currentHeight = contentView.getMeasuredHeight();

        if (currentHeight < minHeight) {
            View messageBodyView = contentView.findViewById(R.id.subTitle);
            messageBodyView.getLayoutParams().height = messageBodyView.getMeasuredHeight() + (minHeight - currentHeight);
        }
    }

    public void setBodyText(String text) {
        if (!TextUtils.isEmpty(text)) {
            ((TextView) mDialogContentView.findViewById(R.id.subTitle)).setText(text);
        }
    }

    public void setBodyLayout(View view) {
        if (view != null) {
            ((LinearLayout) mDialogContentView.findViewById(R.id.content)).addView(view);
        }
    }

    @Override
    public void show() {
        try {
            super.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public interface OnButtonClickListener {
        void onOKButtonClick(FengjrDialog dialog);

        void onCancelButtonClick(FengjrDialog dialog);
    }

    public static class DialogBuilder {

        private boolean useSystemAlert;

        protected String positiveButtonText;
        protected int positiveButtonTextColor;
        protected String negativeButtonText;
        protected int negativeButtonTextColor;
        protected String titleText;
        protected int titleColorResId;
        protected int bodyColorResId;

        protected String bodyText;
        protected boolean buttonInverse;

        protected int bodyTextGravity = Gravity.CENTER;

        protected FengjrDialog dialog;

        protected Context context;

        protected View dialogLayout;

        protected LayoutInflater mInflater;

        private int dialogTitleStyleID;
        private int dialogTextBodyStyleID;
        private int dialogButtonStyleID;

        public DialogBuilder(Context context) {
            this.context = context;
            mInflater = LayoutInflater.from(context);
        }

        /**
         * for use this feature, require permission :
         * android:name="android.permission.SYSTEM_ALERT_WINDOW"
         * android:name="android.permission.SYSTEM_OVERLAY_WINDOW"
         *
         * @return
         */
        public DialogBuilder useSystemAlert() {
            useSystemAlert = true;
            return this;
        }

        public DialogBuilder setPositiveButtonText(String positiveButtonText) {
            this.positiveButtonText = positiveButtonText;
            return this;
        }

        public DialogBuilder setPositiveButtonText(int positiveButtonText) {
            this.positiveButtonText = context.getString(positiveButtonText);
            return this;
        }

        public DialogBuilder setPositiveButtonTextColor(int color) {
            this.positiveButtonTextColor = color;
            return this;
        }

        public DialogBuilder setNegativeButtonText(String negativeButtonText) {
            this.negativeButtonText = negativeButtonText;
            return this;
        }

        public DialogBuilder setNegativeButtonText(int negativeButtonTextId) {
            this.negativeButtonText = context.getString(negativeButtonTextId);
            return this;
        }

        public DialogBuilder setNegativeButtonTextColor(int color) {
            this.negativeButtonTextColor = color;
            return this;
        }

        public DialogBuilder setTitleText(String titleText) {
            this.titleText = titleText;
            return this;
        }

        public DialogBuilder setTitleText(int titleTextResId) {
            this.titleText = context.getString(titleTextResId);
            return this;
        }

        public DialogBuilder setTitleColor(int colorResId) {
            this.titleColorResId = colorResId;
            return this;
        }

        public DialogBuilder setBodyColor(int colorResId) {
            this.bodyColorResId = colorResId;
            return this;
        }

        public DialogBuilder setBodyText(String bodyText) {
            this.bodyText = bodyText;
            return this;
        }

        public DialogBuilder setBodyText(int bodyTextResID) {
            this.bodyText = context.getString(bodyTextResID);
            return this;
        }

        public DialogBuilder setBodyTextGravity(int gravity) {
            this.bodyTextGravity = gravity;
            return this;
        }

        public DialogBuilder inverseButton() {
            buttonInverse = true;
            return this;
        }

        protected void setupViews() {
            dialog.getWindow().getAttributes().gravity = Gravity.CENTER;
            dialogLayout = mInflater.inflate(R.layout.view_dialog, null);

            /****************** apply button's style ******************/
            TypedArray buttonArray = context.obtainStyledAttributes(dialogButtonStyleID, R.styleable.DialogButton);
            Button okBtn = (Button) dialogLayout.findViewById(R.id.positiveButton);
            if (!TextUtils.isEmpty(positiveButtonText)) {
                okBtn.setOnClickListener(dialog);
                okBtn.setText(positiveButtonText);

                if (positiveButtonTextColor != 0) {
                    okBtn.setTextColor(positiveButtonTextColor);
                } else {
                    int textColor = buttonArray.getColor(R.styleable.DialogButton_dialogPositiveTextColor, Integer.MIN_VALUE);
                    if (textColor != Integer.MIN_VALUE) {
                        okBtn.setTextColor(textColor);
                    }
                }

                Drawable okBtnBg = buttonArray.getDrawable(R.styleable.DialogButton_dialogPositiveBg);
                if (okBtnBg != null) {
                    okBtn.setBackgroundDrawable(okBtnBg);
                }
            } else {
                okBtn.setVisibility(View.GONE);
            }

            Button cancelBtn = (Button) dialogLayout.findViewById(R.id.negativeButton);
            if (!TextUtils.isEmpty(negativeButtonText)) {
                cancelBtn.setOnClickListener(dialog);
                cancelBtn.setText(negativeButtonText);

                if (negativeButtonTextColor != 0) {
                    cancelBtn.setTextColor(negativeButtonTextColor);
                } else {
                    int textColor = buttonArray.getColor(R.styleable.DialogButton_dialogNegativeTextColor, Integer.MIN_VALUE);
                    if (textColor != Integer.MIN_VALUE) {
                        cancelBtn.setTextColor(textColor);
                    }
                }

                Drawable cancelBtnBg = buttonArray.getDrawable(R.styleable.DialogButton_dialogNegativeBg);
                if (cancelBtnBg != null) {
                    cancelBtn.setBackgroundDrawable(cancelBtnBg);
                }
            } else {
                cancelBtn.setVisibility(View.GONE);
            }
            buttonArray.recycle();
            /****************** apply button's style ******************/

            /****************** apply title's style ******************/
            TypedArray titleArray = context.obtainStyledAttributes(dialogTitleStyleID, R.styleable.DialogTitle);
            if (!TextUtils.isEmpty(titleText)) {
                TextView titleView = (TextView) dialogLayout.findViewById(R.id.title);
                titleView.setVisibility(View.VISIBLE);
                titleView.setText(titleText);

                if (titleColorResId != 0) {
                    titleView.setTextColor(context.getResources().getColor(titleColorResId));
                } else {
                    int textColor = titleArray.getColor(R.styleable.DialogTitle_android_textColor, Integer.MIN_VALUE);
                    if (textColor != Integer.MIN_VALUE) {
                        titleView.setTextColor(textColor);
                    }
                }

                int textSize = (int) titleArray.getDimension(R.styleable.DialogTitle_android_textSize, Integer.MIN_VALUE);
                if (textSize != Integer.MIN_VALUE) {
                    titleView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
                }

                int paddingLeft = (int) titleArray.getDimension(R.styleable.DialogTitle_android_paddingLeft, Integer.MIN_VALUE);
                int paddingTop = (int) titleArray.getDimension(R.styleable.DialogTitle_android_paddingTop, Integer.MIN_VALUE);
                int paddingRight = (int) titleArray.getDimension(R.styleable.DialogTitle_android_paddingRight, Integer.MIN_VALUE);
                int paddingBottom = (int) titleArray.getDimension(R.styleable.DialogTitle_android_paddingBottom, Integer.MIN_VALUE);
                titleView.setPadding(
                        paddingLeft == Integer.MIN_VALUE ? titleView.getPaddingLeft() : paddingLeft,
                        paddingTop == Integer.MIN_VALUE ? titleView.getPaddingTop() : paddingTop,
                        paddingRight == Integer.MIN_VALUE ? titleView.getPaddingRight() : paddingRight,
                        paddingBottom == Integer.MIN_VALUE ? titleView.getPaddingBottom() : paddingBottom
                );
            }
            titleArray.recycle();
            /****************** apply title's style ******************/

            /****************** apply text body's style ******************/
            TypedArray bodyArray = context.obtainStyledAttributes(dialogTextBodyStyleID, R.styleable.DialogTextBody);
            if (!TextUtils.isEmpty(bodyText)) {
                TextView bodyTextView = (TextView) dialogLayout.findViewById(R.id.subTitle);
                bodyTextView.setVisibility(View.VISIBLE);
                bodyTextView.setText(bodyText);

                if (bodyTextGravity != Integer.MIN_VALUE) {
                    bodyTextView.setGravity(bodyTextGravity);
                }

                if (bodyColorResId != 0) {
                    bodyTextView.setTextColor(context.getResources().getColor(bodyColorResId));
                } else {
                    int textColor = bodyArray.getColor(R.styleable.DialogTextBody_android_textColor, Integer.MIN_VALUE);
                    if (textColor != Integer.MIN_VALUE) {
                        bodyTextView.setTextColor(textColor);
                    }
                }

                int textSize = (int) bodyArray.getDimension(R.styleable.DialogTextBody_android_textSize, Integer.MIN_VALUE);
                if (textSize != Integer.MIN_VALUE) {
                    bodyTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
                }

                int paddingLeft = (int) titleArray.getDimension(R.styleable.DialogTextBody_android_paddingLeft, Integer.MIN_VALUE);
                int paddingTop = (int) titleArray.getDimension(R.styleable.DialogTextBody_android_paddingTop, Integer.MIN_VALUE);
                int paddingRight = (int) titleArray.getDimension(R.styleable.DialogTextBody_android_paddingRight, Integer.MIN_VALUE);
                int paddingBottom = (int) titleArray.getDimension(R.styleable.DialogTextBody_android_paddingBottom, Integer.MIN_VALUE);
                bodyTextView.setPadding(
                        paddingLeft == Integer.MIN_VALUE ? bodyTextView.getPaddingLeft() : paddingLeft,
                        paddingTop == Integer.MIN_VALUE ? bodyTextView.getPaddingTop() : paddingTop,
                        paddingRight == Integer.MIN_VALUE ? bodyTextView.getPaddingRight() : paddingRight,
                        paddingBottom == Integer.MIN_VALUE ? bodyTextView.getPaddingBottom() : paddingBottom
                );
            }
            bodyArray.recycle();
            /****************** apply text body's style ******************/

            dialog.mButtonInverse = buttonInverse;
            dialog.mUseSystemAlert = useSystemAlert;
            dialog.buildDialogInternal(dialogLayout);
        }

        protected int applyDialogTheme() {
            TypedValue outValue = new TypedValue();
            context.getTheme().resolveAttribute(R.attr.DialogStyle, outValue, true);
            final int theme = outValue.resourceId;
            TypedArray array = context.obtainStyledAttributes(theme, R.styleable.Dialog);

            dialogTitleStyleID = array.getResourceId(R.styleable.Dialog_dialogTitleStyle, R.style.DialogText_Title);
            dialogTextBodyStyleID = array.getResourceId(R.styleable.Dialog_dialogTextBodyStyle, R.style.DialogText_Body);
            dialogButtonStyleID = array.getResourceId(R.styleable.Dialog_dialogButtonStyle, R.style.DialogButton);
            array.recycle();

            return theme == 0 ? R.style.DialogDefault : theme;
        }

        public FengjrDialog build() {
            dialog = new FengjrDialog(context, applyDialogTheme());

            setupViews();
            return dialog;
        }
    }
}
